﻿using Microsoft.Extensions.Logging;
using Orleans;
using Orleans.Configuration;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace OrleansTest.Client
{
    class Program
    {
        static void Main(string[] args)
        {
            var client = StartClient();

            while (!client.IsInitialized)
            {
                Console.WriteLine("Connecting to server...");
                Thread.Sleep(1000);
            }
            StartPlayer(client, "1");
            do
            {
                string input = Console.ReadLine();
            }
            while (Console.ReadLine() != "exit");
        }


        static void StartPlayer(IClusterClient client, string tokenId)
        {
            // Use the connected client to call a grain, writing the result to the terminal.
            var player = client.GetGrain<IHello>(1);
            player.SayTo("你好", "翠花").Wait();
            Console.WriteLine($"{tokenId} said 你好 to 翠花");
            //var game = await player.GenerateGame(tokenId);
            //await player.JoinGame(game);
            //await player.LeaveGame(game);
        }

        private static IClusterClient StartClient()
        {
            Guid id = Guid.NewGuid();
            var client = new ClientBuilder()
                    .UseLocalhostClustering(999)
                    .Configure<ClusterOptions>(options =>
                    {
                        options.ClusterId = "dev";
                        options.ServiceId = "GameCenter";
                    })
                    .ConfigureLogging(logging =>
                    {
                        //logging.SetMinimumLevel(LogLevel.Warning);
                        logging.AddConsole();
                    })
                    .Build()
                    ;
            //client.Connect(CreateRetryFilter());
            client.Connect();
            Console.WriteLine("Client successfully connect to silo host");
            return client;
        }
        private static Func<Exception, Task<bool>> CreateRetryFilter(int maxAttempts = 5)
        {
            var attempt = 0;
            return RetryFilter;

            async Task<bool> RetryFilter(Exception exception)
            {
                attempt++;
                Console.WriteLine($"Cluster client attempt {attempt} of {maxAttempts} failed to connect to cluster.  Exception: {exception}");
                if (attempt > maxAttempts)
                {
                    return false;
                }

                await Task.Delay(TimeSpan.FromSeconds(4));
                return true;
            }
        }
    }
}
